home *** CD-ROM | disk | FTP | other *** search
- /***************************************
- $Header: /home/amb/cxref/RCS/latex.c 1.16 1996/02/24 14:53:25 amb Exp $
-
- C Cross Referencing & Documentation tool. Version 1.0
-
- Writes the Latex output.
- ******************/ /******************
- Written by Andrew M. Bishop
-
- This file Copyright 1995,96 Andrew M. Bishop
- It may be distributed under the GNU Public License, version 2, or
- any higher version. See section COPYING of the GNU Public license
- for conditions under which this file may be redistributed.
- ***************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <unistd.h>
-
- #ifndef min
- #define min(x,y) ( (x) < (y) ? (x) : (y) )
- #endif
-
- #include "memory.h"
- #include "datatype.h"
- #include "cxref.h"
-
- /*+ The name of the output tex file that includes each of the others. +*/
- #define LATEX_FILE ".tex"
- #define LATEX_FILE_BACKUP ".tex~"
-
- /*+ The name of the output tex file that contains the appendix. +*/
- #define LATEX_APDX_FILE ".apdx.tex"
-
- /*+ The type of LaTeX output to produce. +*/
- extern int option_latex;
-
- /*+ The name of the directory for the output. +*/
- extern char* option_odir;
-
- /*+ The base name of the file for the output. +*/
- extern char* option_name;
-
- extern char *latex_page_style,*latex_fonts_style;
-
- static void WriteLatexFilePart(File file);
- static void WriteLatexInclude(Include inc);
- static void WriteLatexSubInclude(Include inc,int depth);
- static void WriteLatexDefine(Define def);
- static void WriteLatexTypedef(Typedef type,char* filename);
- static void WriteLatexStructUnion(StructUnion su, int depth);
- static void WriteLatexVariable(Variable var,char* filename);
- static void WriteLatexFunction(Function func,char* filename);
-
- static void WriteLatexDocument(char* name);
- static void WriteLatexPreamble(FILE* f);
- static void WriteLatexPostamble(FILE* f);
- static void AddLatexAppendix(void);
-
- static char* latex(char* c);
-
- /*+ The output file for the latex. +*/
- static FILE* of;
-
- /*+ Counts the lines in a table to insert breaks. +*/
- static int countlines=0;
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a Latex file for a complete File structure and all components.
-
- File file The File structure to output.
- ++++++++++++++++++++++++++++++++++++++*/
-
- void WriteLatexFile(File file)
- {
- char* ofile;
-
- /* Write the including file. */
-
- WriteLatexDocument(file->name);
-
- /* Open the file */
-
- ofile=ConcatStrings(4,option_odir,"/",file->name,LATEX_FILE);
-
- of=fopen(ofile,"w");
-
- if(!of)
- {fprintf(stderr,"cxref: Failed to open the LaTeX output file '%s'\n",ofile);exit(1);}
-
- /* Write out a header. */
-
- fputs("% This LaTeX file generated by cxref\n",of);
- fputs("% cxref program (c) Andrew M. Bishop 1995,96.\n",of);
- fputs("\n",of);
-
- /*+ The file structure is broken into its components and they are each written out. +*/
-
- WriteLatexFilePart(file);
-
- if(file->includes)
- {
- Include inc =file->includes;
- fprintf(of,"\\subsection*{Included Files}\n\n");
- do{
- if(inc!=file->includes)
- fprintf(of,"\\medskip\n");
- WriteLatexInclude(inc);
- }
- while((inc=inc->next));
- }
-
- if(file->defines)
- {
- Define def =file->defines;
- fprintf(of,"\\subsection*{Preprocessor definitions}\n\n");
- do{
- if(def!=file->defines)
- fprintf(of,"\\medskip\n");
- WriteLatexDefine(def);
- }
- while((def=def->next));
- }
-
- if(file->typedefs)
- {
- Typedef type=file->typedefs;
- fprintf(of,"\\subsection{Type definitions}\n\n");
- do{
- WriteLatexTypedef(type,file->name);
- }
- while((type=type->next));
- }
-
- if(file->variables)
- {
- int any_to_mention=0;
- Variable var=file->variables;
-
- do{
- if(var->scope&(GLOBAL|LOCAL|EXTERNAL))
- any_to_mention=1;
- }
- while((var=var->next));
-
- if(any_to_mention)
- {
- int first_ext=1,first_local=1;
- Variable var=file->variables;
- fprintf(of,"\\subsection{Variables}\n\n");
- do{
- if(var->scope&GLOBAL)
- WriteLatexVariable(var,file->name);
- }
- while((var=var->next));
- var=file->variables;
- do{
- if(var->scope&EXTERNAL && !(var->scope&GLOBAL))
- {
- if(first_ext)
- {fprintf(of,"\\subsubsection{External Variables}\n\n"); first_ext=0;}
- else
- fprintf(of,"\\medskip\n");
- WriteLatexVariable(var,file->name);
- }
- }
- while((var=var->next));
- var=file->variables;
- do{
- if(var->scope&LOCAL)
- {
- if(first_local)
- {fprintf(of,"\\subsubsection{Local Variables}\n\n"); first_local=0;}
- else
- fprintf(of,"\\medskip\n");
- WriteLatexVariable(var,file->name);
- }
- }
- while((var=var->next));
- }
- }
-
- if(file->functions)
- {
- Function func=file->functions;
- fprintf(of,"\\subsection{Functions}\n\n");
- do{
- if(func->scope&GLOBAL)
- WriteLatexFunction(func,file->name);
- }
- while((func=func->next));
- func=file->functions;
- do{
- if(func->scope&LOCAL)
- WriteLatexFunction(func,file->name);
- }
- while((func=func->next));
- }
-
- fclose(of);
-
- /* Clear the memory in latex() */
-
- latex(NULL); latex(NULL); latex(NULL); latex(NULL);
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a File structure out.
-
- File file The File to output.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexFilePart(File file)
- {
- int i;
-
- fprintf(of,"\\markboth{File %s}{File %s}\n",latex(file->name),latex(file->name));
- fprintf(of,"\\section{File %s}\n",latex(file->name));
- fprintf(of,"\\label{file_%s}\n\n",file->name);
-
- if(file->comment)
- {
- char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL;
- if(rcs1)
- {
- rcs2=strstr(&rcs1[1],"$");
- if(rcs2)
- {
- rcs2[0]=0;
- fprintf(of,"{\\bf RCS %s}\n\n",latex(&rcs1[1]));
- fprintf(of,"\\smallskip\n");
- rcs2[0]='$';
- }
- }
- if(rcs2)
- fprintf(of,"%s\n\n",latex(&rcs2[2]));
- else
- fprintf(of,"%s\n\n",latex(file->comment));
- }
-
- if(file->inc_in.n)
- {
- int i;
-
- if(file->comment)
- fprintf(of,"\\medskip\n");
- fprintf(of,"\\begin{cxreftabii}\nIncluded in:");
- for(i=0;i<file->inc_in.n;i++)
- {/* Allow a break in every 8 (or so) items to stop allow the table to break over the page. */
- if(min(i,file->inc_in.n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabii}\n");
- fprintf(of,"\\ & %s & \\cxreffile{%s}\\\\\n",latex(file->inc_in.s[i]),file->inc_in.s[i]);
- }
- fprintf(of,"\\end{cxreftabii}\n\n");
- }
-
- if(file->f_refs.n || file->v_refs.n)
- {
- int tabcount=0;
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxreftabiii}\n");
-
- if(file->f_refs.n)
- {
- int others=0;
- for(i=0;i<file->f_refs.n;i++)
- {
- char *temp=strchr(file->f_refs.s[i],':'),*filen;
- if(temp)
- {
- temp[-1]=0;
- filen=&temp[2];
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==others)
- fprintf(of,"Refs Func:");
- fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(file->f_refs.s[i]),latex(filen),file->f_refs.s[i],filen);
- temp[-1]=' ';
- }
- else
- others++;
- }
-
- if(others)
- {
- if(others==file->f_refs.n)
- fprintf(of,"Refs Func:");
- fprintf(of,"\\ & \\twocoltabiii{");
- for(i=0;i<file->f_refs.n;i++)
- if(!strchr(file->f_refs.s[i],':'))
- fprintf(of,--others?" %s(),":" %s()",latex(file->f_refs.s[i]));
- fprintf(of,"} &\\\\\n");
- }
- }
-
- if(file->v_refs.n)
- {
- int others=0;
- for(i=0;i<file->v_refs.n;i++)
- {
- char *temp=strchr(file->v_refs.s[i],':'),*filen;
- if(temp)
- {
- temp[-1]=0;
- filen=&temp[2];
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==others)
- fprintf(of,"Refs Var:");
- fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(file->v_refs.s[i]),latex(filen),file->v_refs.s[i],filen);
- temp[-1]=' ';
- }
- else
- others++;
- }
-
- if(others)
- {
- if(others==file->v_refs.n)
- fprintf(of,"Refs Var:");
- fprintf(of,"\\ & \\twocoltabiii{");
- for(i=0;i<file->v_refs.n;i++)
- if(!strchr(file->v_refs.s[i],':'))
- fprintf(of,--others?" %s,":" %s",latex(file->v_refs.s[i]));
- fprintf(of,"} &\\\\\n");
- }
- }
-
- fprintf(of,"\\end{cxreftabiii}\n\n");
- }
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write an Include structure out.
-
- Include inc The Include structure to output.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexInclude(Include inc)
- {
- if(inc->comment)
- fprintf(of,"%s\n\n\\smallskip\n",latex(inc->comment));
-
- fprintf(of,"\\begin{cxreftabi}\n"); countlines=1;
-
- if(inc->scope==LOCAL)
- fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name),inc->name);
- else
- fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name));
-
- if(inc->includes)
- WriteLatexSubInclude(inc->includes,1);
-
- fprintf(of,"\\end{cxreftabi}\n\n");
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write an Sub Include structure out. (An include structure that is included from another file.)
-
- Include inc The Include structure to output.
-
- int depth The depth of the include hierarchy.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexSubInclude(Include inc,int depth)
- {
- while(inc)
- {
- if(countlines++%8==4)
- fprintf(of,"\\cxreftabbreak{cxreftabi}\n");
-
- fprintf(of,"\\hspace*{%3.1fin}",0.2*depth);
-
- if(inc->scope==LOCAL)
- fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name),inc->name);
- else
- fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name));
-
- if(inc->includes)
- WriteLatexSubInclude(inc->includes,depth+1);
-
- inc=inc->next;
- }
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a Define structure out.
-
- Define def The Define structure to output.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexDefine(Define def)
- {
- int i;
- int pargs=0;
-
- if(def->comment)
- fprintf(of,"%s\n\n\\smallskip\n",latex(def->comment));
-
- fprintf(of,"{\\stt \\#define %s",latex(def->name));
-
- if(def->value)
- fprintf(of," %s",latex(def->value));
-
- if(def->args.n)
- {
- fprintf(of,"( ");
- for(i=0;i<def->args.n;i++)
- fprintf(of,i?", %s":"%s",latex(def->args.s1[i]));
- fprintf(of," )");
- }
- fprintf(of,"}\n\n");
-
- for(i=0;i<def->args.n;i++)
- if(def->args.s2[i])
- pargs=1;
-
- if(pargs)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxrefarglist}\n");
- for(i=0;i<def->args.n;i++)
- fprintf(of,"\\cxrefargitem{%s} %s\n",latex(def->args.s1[i]),def->args.s2[i]?latex(def->args.s2[i]):"\\ ");
- fprintf(of,"\\end{cxrefarglist}\n\n");
- }
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a Typedef structure out.
-
- Typedef type The Typedef structure to output.
-
- char* filename The name of the file that is being processed (required for the cross reference label).
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexTypedef(Typedef type,char* filename)
- {
- if(type->type)
- fprintf(of,"\\subsubsection{Typedef %s}\n",latex(type->name));
- else
- fprintf(of,"\\subsubsection{Type %s}\n",latex(type->name));
-
- if(!strncmp("enum",type->name,4))
- fprintf(of,"\\label{type_enum_%s_%s}\n\n",&type->name[5],filename);
- else
- if(!strncmp("union",type->name,5))
- fprintf(of,"\\label{type_union_%s_%s}\n\n",&type->name[6],filename);
- else
- if(!strncmp("struct",type->name,6))
- fprintf(of,"\\label{type_struct_%s_%s}\n\n",&type->name[7],filename);
- else
- fprintf(of,"\\label{type_%s_%s}\n\n",type->name,filename);
-
- if(type->comment)
- fprintf(of,"%s\n\n\\smallskip\n",latex(type->comment));
-
- if(type->type)
- fprintf(of,"{\\stt typedef %s}\n\n",latex(type->type));
-
- if(type->sutype)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxreftabiia}\n"); countlines=0;
- WriteLatexStructUnion(type->sutype,0);
- fprintf(of,"\\end{cxreftabiia}\n\n");
- }
- else
- if(type->typexref)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxreftabii}\n");
- if(type->typexref->type)
- fprintf(of,"See:& Typedef %s & \\cxreftype{%s}{%s}\\\\\n",latex(type->typexref->name),type->typexref->name,filename);
- else
- if(!strncmp("enum",type->typexref->name,4))
- fprintf(of,"See:& Type %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[5],filename);
- else
- if(!strncmp("union",type->typexref->name,5))
- fprintf(of,"See:& Type %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[6],filename);
- else
- if(!strncmp("struct",type->typexref->name,6))
- fprintf(of,"See:& Type %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[7],filename);
- fprintf(of,"\\end{cxreftabii}\n\n");
- }
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a structure / union structure out.
-
- StructUnion su The structure / union to write.
-
- int depth The current depth within the structure.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexStructUnion(StructUnion su, int depth)
- {
- int i;
- char* splitsu=NULL;
-
- splitsu=strstr(su->name,"{...}");
- if(splitsu) splitsu[-1]=0;
-
- if(countlines++%8==4)
- fprintf(of,"\\cxreftabbreak{cxreftabiia}\n");
- fprintf(of,"\\hspace*{%3.1fin}",0.2*depth);
-
- if(depth && su->comment)
- fprintf(of,"{\\stt %s} & %s \\\\\n",latex(su->name),latex(su->comment));
- else
- fprintf(of,"{\\stt %s} &\\\\\n",latex(su->name));
-
- if(su->comps)
- {
- fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
- fprintf(of,"{\\stt \\{} &\\\\\n");
-
- for(i=0;i<su->n_comp;i++)
- WriteLatexStructUnion(su->comps[i],depth+1);
-
- fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
- fprintf(of,"{\\stt \\}} &\\\\\n");
- if(splitsu)
- {
- fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
- fprintf(of,"{\\stt %s} &\\\\\n",latex(&splitsu[6]));
- }
- }
-
- if(splitsu) splitsu[-1]=' ';
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a Variable structure out.
-
- Variable var The Variable structure to output.
-
- char* filename The name of the file that is being processed (required for the cross reference label).
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexVariable(Variable var,char* filename)
- {
- int i;
-
- if(var->scope&GLOBAL)
- fprintf(of,"\\subsubsection{Variable %s}\n",latex(var->name));
- else
- fprintf(of,"{\\bf %s}\n",latex(var->name));
-
- fprintf(of,"\\label{var_%s_%s}\n\n",var->name,filename);
-
- if(var->comment)
- fprintf(of,"%s\n\n\\smallskip\n",latex(var->comment));
-
- switch(var->scope)
- {
- case LOCAL:
- fprintf(of,"{\\stt static %s}\n\n",latex(var->type));
- break;
- case EXTERNAL:
- fprintf(of,"{\\stt extern %s}\n\n",latex(var->type));
- break;
- default:
- fprintf(of,"{\\stt %s}\n\n",latex(var->type));
- break;
- }
-
- if(var->scope&(GLOBAL|LOCAL))
- {
- if(var->used.n || var->visible.n)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxreftabiii}\n");
-
- for(i=0;i<var->visible.n;i++)
- {
- if(min(i,var->visible.n+var->used.n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==0) fprintf(of,"Visible in:");
- fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->visible.s[i]),var->visible.s[i]);
- }
-
- for(i=0;i<var->used.n;i++)
- {
- if(min(i,var->visible.n+var->used.n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==0) fprintf(of,"Used in:");
- if(var->used.s[i][0]=='$')
- fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(&var->used.s[i][1]),&var->used.s[i][1]);
- else
- {
- char *temp=strchr(var->used.s[i],':'),*file;
- temp[-1]=0;
- file=&temp[2];
- if(var->scope&LOCAL)
- fprintf(of,"\\ & %s() & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used.s[i]),var->used.s[i],file);
- else
- fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used.s[i]),latex(file),var->used.s[i],file);
- temp[-1]=' ';
- }
- }
-
- fprintf(of,"\\end{cxreftabiii}\n\n");
- }
- }
- else
- if(var->scope&EXTERNAL && var->defined)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxreftabiii}\n");
- fprintf(of,"Defined in:& %s & \\ & \\cxrefvar{%s}{%s}",latex(var->defined),var->name,var->defined);
- fprintf(of,"\\end{cxreftabiii}\n\n");
- }
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write a Function structure out.
-
- Function func The Function structure to output.
-
- char* filename The name of the file that is being processed (required for the cross reference label).
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexFunction(Function func,char* filename)
- {
- int i,pret,pargs;
- char* comment2=NULL,*type;
-
- if(func->scope&GLOBAL)
- fprintf(of,"\\subsubsection{Global Function %s()}\n",latex(func->name));
- else
- fprintf(of,"\\subsubsection{Local Function %s()}\n",latex(func->name));
- fprintf(of,"\\label{func_%s_%s}\n\n",func->name,filename);
-
- if(func->comment)
- {
- comment2=strstr(func->comment,"\n\n");
- if(comment2)
- comment2[0]=0;
- fprintf(of,"%s\n\n",latex(func->comment));
- fprintf(of,"\\smallskip\n");
- }
-
- fprintf(of,"{\\stt ");
- switch(func->scope)
- {
- case LOCAL: fprintf(of,"static "); break;
- case LOCAL+INLINED: fprintf(of,"static inline "); break;
- case INLINED: fprintf(of,"inline "); break;
- default: ;
- }
-
- if((type=strstr(func->type,"()")))
- type[0]=0;
- fprintf(of,"%s ( ",latex(func->type));
-
- for(i=0;i<func->args.n;i++)
- fprintf(of,i?", %s":"%s",latex(func->args.s1[i]));
-
- if(type)
- {fprintf(of," %s}\n\n",&type[1]);type[0]='(';}
- else
- fprintf(of," )}\n\n");
-
- pret =strncmp("void ",func->type,5) && func->cret;
- for(pargs=0,i=0;i<func->args.n;i++)
- pargs = pargs || ( strcmp("void",func->args.s1[i]) && func->args.s2[i] );
-
- if(pret || pargs)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxrefarglist}\n");
- if(pret)
- fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->type),func->cret?latex(func->cret):"\\ ");
- if(pargs)
- for(i=0;i<func->args.n;i++)
- fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->args.s1[i]),func->args.s2[i]?latex(func->args.s2[i]):"\\ ");
- fprintf(of,"\\end{cxrefarglist}\n\n");
- }
-
- if(comment2)
- {
- fprintf(of,"\\smallskip\n");
- fprintf(of,"%s\n\n",latex(&comment2[2]));
- comment2[0]='\n';
- }
-
- if(func->protofile || func->calls.n || func->called.n || func->used.n || func->f_refs.n || func->v_refs.n)
- {
- int tabcount=func->protofile?1:0;
- fprintf(of,"\\smallskip\n");
- fprintf(of,"\\begin{cxreftabiii}\n");
-
- if(func->protofile)
- fprintf(of,"Prototype:& %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->protofile),func->protofile);
-
- if(func->calls.n)
- {
- int others=0;
- for(i=0;i<func->calls.n;i++)
- {
- char *temp=strchr(func->calls.s[i],':'),*file;
- if(temp)
- {
- temp[-1]=0;
- file=&temp[2];
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==others)
- fprintf(of,"Calls:");
- fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->calls.s[i]),latex(file),func->calls.s[i],file);
- temp[-1]=' ';
- }
- else
- others++;
- }
-
- if(others)
- {
- if(others==func->calls.n)
- fprintf(of,"Calls:");
- fprintf(of,"\\ & \\twocoltabiii{");
- for(i=0;i<func->calls.n;i++)
- if(!strchr(func->calls.s[i],':'))
- fprintf(of,--others?" %s(),":" %s()",latex(func->calls.s[i]));
- fprintf(of,"} &\\\\\n");
- }
- }
-
- if(func->called.n)
- {
- for(i=0;i<func->called.n;i++)
- {
- char *temp=strchr(func->called.s[i],':'),*file;
- temp[-1]=0;
- file=&temp[2];
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==0)
- fprintf(of,"Called by:");
- fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->called.s[i]),latex(file),func->called.s[i],file);
- temp[-1]=' ';
- }
- }
-
- if(func->used.n)
- {
- for(i=0;i<func->used.n;i++)
- {
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==0)
- fprintf(of,"Used in:");
- if(func->used.s[i][0]=='$')
- fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(&func->used.s[i][1]),&func->used.s[i][1]);
- else
- {
- char *temp=strchr(func->used.s[i],':'),*file;
- temp[-1]=0;
- file=&temp[2];
- fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->used.s[i]),latex(file),func->used.s[i],file);
- temp[-1]=' ';
- }
- }
- }
-
- if(func->f_refs.n)
- {
- int others=0;
- for(i=0;i<func->f_refs.n;i++)
- {
- char *temp=strchr(func->f_refs.s[i],':'),*file;
- if(temp)
- {
- temp[-1]=0;
- file=&temp[2];
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==others)
- fprintf(of,"Refs Func:");
- fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->f_refs.s[i]),latex(file),func->f_refs.s[i],file);
- temp[-1]=' ';
- }
- else
- others++;
- }
-
- if(others)
- {
- if(others==func->f_refs.n)
- fprintf(of,"Refs Func:");
- fprintf(of,"\\ & \\twocoltabiii{");
- for(i=0;i<func->f_refs.n;i++)
- if(!strchr(func->f_refs.s[i],':'))
- fprintf(of,--others?" %s(),":" %s()",latex(func->f_refs.s[i]));
- fprintf(of,"} &\\\\\n");
- }
- }
-
- if(func->v_refs.n)
- {
- int others=0;
- for(i=0;i<func->v_refs.n;i++)
- {
- char *temp=strchr(func->v_refs.s[i],':'),*file;
- if(temp)
- {
- temp[-1]=0;
- file=&temp[2];
- if(++tabcount%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
- if(i==others)
- fprintf(of,"Refs Var:");
- fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(func->v_refs.s[i]),latex(file),func->v_refs.s[i],file);
- temp[-1]=' ';
- }
- else
- others++;
- }
-
- if(others)
- {
- if(others==func->v_refs.n)
- fprintf(of,"Refs Var:");
- fprintf(of,"\\ & \\twocoltabiii{");
- for(i=0;i<func->v_refs.n;i++)
- if(!strchr(func->v_refs.s[i],':'))
- fprintf(of,--others?" %s,":" %s",latex(func->v_refs.s[i]));
- fprintf(of,"} &\\\\\n");
- }
- }
-
- fprintf(of,"\\end{cxreftabiii}\n\n");
- }
-
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write out a file that will include the current information.
-
- char* name The name of the file.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexDocument(char* name)
- {
- FILE *in,*out;
- char line[256];
- int seen=0;
- char *inc_file,*ofile,*ifile;
-
- inc_file=ConcatStrings(3,"\\input{",name,LATEX_FILE"}\n");
- ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE);
- ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP);
-
- in =fopen(ifile,"r");
- out=fopen(ofile,"w");
-
- if(!out)
- {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);exit(1);}
-
- if(!in)
- WriteLatexPreamble(out);
-
- if(in)
- while(fgets(line,256,in))
- {
- if(!strcmp(inc_file,line))
- seen=1;
- if(line[0]=='%' && (!strcmp("% Appendix\n",line) || !strcmp("% Contents\n",line)) && !seen)
- {fputs(inc_file,out);fputs("\n",out);seen=1;}
- fputs(line,out);
- }
-
- if(!in)
- {
- fputs(inc_file,out);
- WriteLatexPostamble(out);
- }
-
- if(in)
- {
- fclose(in);
- unlink(ifile);
- }
-
- fclose(out);
- rename(ofile,ifile);
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write out a standard pre-amble. This sets up the page style and defines some macros.
-
- FILE* f The file to write the pre amble to.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexPreamble(FILE* f)
- {
- struct stat stat_buf;
- char* fname;
-
- fname=ConcatStrings(2,option_odir,"/fonts.sty");
- if(stat(fname,&stat_buf)==-1)
- {
- FILE* file=fopen(fname,"w");
- if(!file)
- {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
- fputs(latex_fonts_style,file);
- fclose(file);
- }
-
- fname=ConcatStrings(2,option_odir,"/page.sty");
- if(stat(fname,&stat_buf)==-1)
- {
- FILE* file=fopen(fname,"w");
- if(!file)
- {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
- fputs(latex_page_style,file);
- fclose(file);
- }
-
- fputs("% This LaTeX file generated by cxref\n",f);
- fputs("% cxref program (c) Andrew M. Bishop 1995,96.\n",f);
- fputs("\n",f);
- if(option_latex==1)
- fputs("\\documentstyle[fonts,page]{report}\n",f);
- else
- {
- fputs("\\documentclass{report}\n",f);
- fputs("\\usepackage{fonts,page}\n",f);
- }
- fputs("\\pagestyle{myheadings}\n",f);
- fputs("\\begin{document}\n",f);
- fputs("\n",f);
- fputs("\\setcounter{secnumdepth}{3}\n",f);
- fputs("\\setcounter{tocdepth}{3}\n",f);
- fputs("\n",f);
- fputs("\\setlength{\\parindent}{0in}\n",f);
- fputs("\\setlength{\\tabcolsep}{0in}\n",f);
- fputs("\n",f);
- fputs("\\newcommand{\\stt}{\\small\\tt}\n",f);
- fputs("\n",f);
- fputs("\\newenvironment{cxrefarglist}{\\begin{list}{}{\\leftmargin=2.25in \\labelsep=0in \\labelwidth=2.25in \\itemsep=0pt \\parsep=3pt \\topsep=3pt}}{\\end{list}}\n",f);
- fputs("\\newcommand{\\cxrefargitem}[1]{\\item[\\parbox{2.25in}{$\\cdot$\\hspace*{0.1in}{\\stt #1}}]}\n",f);
- fputs("\n",f);
- fputs("\\newenvironment{cxreftabi}{\\begin{tabular}{{p{5.0in}l}}}{\\end{tabular}}\n",f);
- fputs("\\newenvironment{cxreftabii}{\\begin{tabular}{{p{0.75in}p{4.25in}l}}}{\\end{tabular}}\n",f);
- fputs("\\newenvironment{cxreftabiia}{\\begin{tabular}{{p{2.5in}p{3.5in}}}}{\\end{tabular}}\n",f);
- fputs("\\newenvironment{cxreftabiib}{\\begin{tabular}{{p{2.5in}p{2.5in}l}}}{\\end{tabular}}\n",f);
- fputs("\\newenvironment{cxreftabiii}{\\begin{tabular}{{p{0.75in}p{2.25in}p{2.0in}l}}}{\\end{tabular}}\n",f);
- fputs("\\newcommand{\\twocoltabiii}[1]{\\multicolumn{2}{p{4.25in}}{#1}}\n",f);
- fputs("\n",f);
- fputs("\\newcommand{\\cxreftabbreak}[1]{\\end{#1}\\vskip 0pt\\begin{#1}}\n",f);
- fputs("\n",f);
- fputs("\\newcommand{\\cxreffile}[1]{{\\small\\it (Section \\ref{file_#1})\\/}}\n",f);
- fputs("\\newcommand{\\cxreffunc}[2]{{\\small\\it (Section \\ref{func_#1_#2})\\/}}\n",f);
- fputs("\\newcommand{\\cxrefvar}[2]{{\\small\\it (Section \\ref{var_#1_#2})\\/}}\n",f);
- fputs("\\newcommand{\\cxreftype}[2]{{\\small\\it (Section \\ref{type_#1_#2})\\/}}\n",f);
- fputs("\n",f);
- fputs("% Begin-Of-Doc\n",f);
- fputs("\n",f);
- fputs("\\chapter{Chapter heading}\n",f);
- fputs("\n",f);
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write out a standard post-amble. This includes a table of contents and the end of document marker.
-
- FILE* f The file to write the post amble to.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void WriteLatexPostamble(FILE* f)
- {
- fputs("\n",f);
- fputs("% Contents\n",f);
- fputs("\n",f);
- fputs("\\markboth{Contents}{Contents}\n",f);
- fputs("\\tableofcontents\n",f);
- fputs("\n",f);
- fputs("% End-Of-Doc\n",f);
- fputs("\n",f);
- fputs("\\end{document}\n",f);
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Write out the appendix information.
-
- StringList* files The list of files to write.
-
- StringList* funcs The list of functions to write.
-
- StringList* vars The list of variables to write.
-
- StringList* types The list of types to write.
- ++++++++++++++++++++++++++++++++++++++*/
-
- void WriteLatexAppendix(StringList* files,StringList* funcs,StringList* vars,StringList* types)
- {
- char* ofile;
- int i;
-
- /* Write the bits to the including file. */
-
- AddLatexAppendix();
-
- /* Open the file */
-
- ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_APDX_FILE);
-
- of=fopen(ofile,"w");
-
- if(!of)
- {fprintf(stderr,"cxref: Failed to open the LaTeX appendix file '%s'\n",ofile);exit(1);}
-
- /* Write the file structure out */
-
- fprintf(of,"\\chapter{Cross References}\n\n");
-
- /* Write out the appendix of files. */
-
- if(files->n)
- {
- fprintf(of,"\\section{Files}\n");
- fprintf(of,"\\label{appendix_file}\n\n");
- fprintf(of,"\\begin{cxreftabiib}\n");
- for(i=0;i<files->n;i++)
- {
- if(min(i,files->n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
- fprintf(of,"%s & \\ & \\cxreffile{%s}\\\\\n",latex(files->s[i]),files->s[i]);
- }
- fprintf(of,"\\end{cxreftabiib}\n\n");
- }
-
- /* Write out the appendix of functions. */
-
- if(funcs->n)
- {
- fprintf(of,"\\section{Global Functions}\n");
- fprintf(of,"\\label{appendix_func}\n\n");
- fprintf(of,"\\begin{cxreftabiib}\n");
- for(i=0;i<funcs->n;i++)
- {
- char *temp=strchr(funcs->s[i],':'),*file;
- temp[-1]=0;
- file=&temp[2];
- if(min(i,funcs->n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
- fprintf(of,"%s & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(funcs->s[i]),latex(file),funcs->s[i],file);
- temp[-1]=' ';
- }
- fprintf(of,"\\end{cxreftabiib}\n\n");
- }
-
- /* Write out the appendix of variables. */
-
- if(vars->n)
- {
- fprintf(of,"\\section{Global Variables}\n");
- fprintf(of,"\\label{appendix_var}\n\n");
- fprintf(of,"\\begin{cxreftabiib}\n");
- for(i=0;i<vars->n;i++)
- {
- char *temp=strchr(vars->s[i],':'),*file;
- temp[-1]=0;
- file=&temp[2];
- if(min(i,vars->n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
- fprintf(of,"%s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(vars->s[i]),latex(file),vars->s[i],file);
- temp[-1]=' ';
- }
- fprintf(of,"\\end{cxreftabiib}\n\n");
- }
-
- /* Write out the appendix of types. */
-
- if(types->n)
- {
- fprintf(of,"\\section{Defined Types}\n");
- fprintf(of,"\\label{appendix_type}\n\n");
- fprintf(of,"\\begin{cxreftabiib}\n");
- for(i=0;i<types->n;i++)
- {
- char *temp=strchr(types->s[i],':'),*file;
- temp[-1]=0;
- file=&temp[2];
- if(min(i,types->n-i)%8 == 4)
- fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
- if(!strncmp("enum",types->s[i],4))
- fprintf(of,"%s & %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(types->s[i]),latex(file),&types->s[i][5],file);
- else
- if(!strncmp("union",types->s[i],5))
- fprintf(of,"%s & %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(types->s[i]),latex(file),&types->s[i][6],file);
- else
- if(!strncmp("struct",types->s[i],6))
- fprintf(of,"%s & %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(types->s[i]),latex(file),&types->s[i][7],file);
- else
- fprintf(of,"%s & %s & \\cxreftype{%s}{%s}\\\\\n",latex(types->s[i]),latex(file),types->s[i],file);
- temp[-1]=' ';
- }
- fprintf(of,"\\end{cxreftabiib}\n\n");
- }
-
- fclose(of);
-
- /* Clear the memory in latex() */
-
- latex(NULL); latex(NULL); latex(NULL); latex(NULL);
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Add the appendix commands to the output file.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static void AddLatexAppendix(void)
- {
- FILE *in,*out;
- char line[256];
- int seen=0;
- char *inc_file,*ofile,*ifile;
-
- inc_file=ConcatStrings(3,"\\input{",option_name,LATEX_APDX_FILE"}\n");
- ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE);
- ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP);
-
- in =fopen(ifile,"r");
- out=fopen(ofile,"w");
-
- if(!in || !out)
- {fprintf(stderr,"cxref: Failed to open the LaTeX main output file '%s'\n",ofile);exit(1);}
-
- while(fgets(line,256,in))
- {
- if(!strcmp("% Appendix\n",line))
- seen=1;
- if(!strcmp("% Contents\n",line) && !seen)
- {
- fputs("% Appendix\n\n",out);
- fputs("\\appendix\n",out);
- fputs("\\markboth{Appendix}{Appendix}\n",out);
- fputs(inc_file,out);
- fputs("\n",out);
- }
- fputs(line,out);
- }
-
- fclose(in);
- if(!seen)
- unlink(ifile);
-
- fclose(out);
- if(!seen)
- rename(ofile,ifile);
- }
-
-
- /*++++++++++++++++++++++++++++++++++++++
- Make the input string safe to output as LaTeX ( not #, $, %, &, \, ^, _, {, }, <, > or ~ ).
-
- char* latex Returns a safe LaTeX string.
-
- char* c A non-safe LaTeX string.
-
- The function can only be called four times in each fprintf() since it returns one of only four static strings.
- ++++++++++++++++++++++++++++++++++++++*/
-
- static char* latex(char* c)
- {
- static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL};
- static int which=0;
- int i=0,j=0,len=256-12; /* 12 is the longest possible inserted amount */
- char* ret;
-
- which=(which+1)%4;
- ret=safe[which];
-
- if(malloced[which])
- {Free(malloced[which]);malloced[which]=NULL;}
-
- if(c)
- do{
- for(;j<len && c[i];i++)
- switch(c[i])
- {
- case '<':
- case '>':
- ret[j++]='$';
- ret[j++]=c[i];
- ret[j++]='$';
- break;
- case '\\':
- strcpy(&ret[j],"$\\backslash$");j+=12;
- break;
- case '~':
- strcpy(&ret[j],"$\\sim$");j+=6;
- break;
- case '^':
- strcpy(&ret[j],"$\\wedge$");j+=8;
- break;
- case '-':
- ret[j++]='-';
- ret[j++]='-';
- break;
- case '#':
- case '$':
- case '%':
- case '&':
- case '_':
- case '{':
- case '}':
- ret[j++]='\\';
- default: /* fall through */
- ret[j++]=c[i];
- }
-
- if(c[i]) /* Not finished */
- {
- unsigned int est_size=(110*strlen(c)*j)/(100*i); /* guess 10% larger than current estimate */
-
- if(malloced[which])
- malloced[which]=Realloc(malloced[which],est_size);
- else
- {malloced[which]=Malloc(est_size); strncpy(malloced[which],ret,(unsigned)j);}
- ret=malloced[which];
- len=est_size-12;
- }
- else
- {ret[j]=0; ret=NULL;}
- }
- while(ret);
- else
- safe[which][0]=0;
-
- return(malloced[which]?malloced[which]:safe[which]);
- }
-